import os, sys
import subprocess
import threading


class MedusaWSGI:
    def __init__(self):
        pass

    def run_with_cgi(self, application):
        environ = dict(os.environ.items())
        environ['wsgi.input']        = sys.stdin
        environ['wsgi.errors']       = sys.stderr
        environ['wsgi.version']      = (1,0)
        environ['wsgi.multithread']  = False
        environ['wsgi.multiprocess'] = True
        environ['wsgi.run_once']    = True


        headers_set = []
        headers_sent = []

        def write(data):
            if not headers_set:
                raise AssertionError("write() before start_response()")

            elif not headers_sent:
                # Before the first output, send the stored headers
                status, response_headers = headers_sent[:] = headers_set
                sys.stdout.write("%s\r\n" % status.split()[0])
                for header in response_headers:
                    sys.stdout.write('%s: %s\r\n' % header)
                sys.stdout.write('\r\n')

            sys.stdout.write(data)
            sys.stdout.flush()

        def start_response(status,response_headers,exc_info=None):
            if exc_info:
                try:
                    if headers_sent:
                        # Re-raise original exception if headers sent
                        raise exc_info[0], exc_info[1], exc_info[2]
                finally:
                    exc_info = None     # avoid dangling circular ref
            elif headers_set:
                raise AssertionError("Headers already set!")

            headers_set[:] = [status,response_headers]
            return write

        result = application(environ, start_response)
        try:
            for data in result:
                if data:    # don't send headers until body appears
                    write(data)
            if not headers_sent:
                write('')   # send headers now if body was empty
        finally:
            if hasattr(result,'close'):
                result.close()


def get_proc_handle(proc_path):
    runner = proc_path.split(".")
    module_name = runner[0]
    try:
        # Try to import as if everything is a module
        for i in xrange(1, len(runner)):
            try:
                __import__(".".join(runner[0:i]))
            except Exception, e:
                pass

        # Try to get using attributes
        _proc = __import__(module_name)
        for r in runner[1:]:
            _proc = getattr(_proc, r)
        return _proc
    except Exception, e:
        print "Caught exception: %s" % str(e)
        return None


def main(argc, argv):
    try:
        # First expand all variables in sys.path or else import complains
        pathVars = set()
        for p in sys.path:
            for i in p.split(";"):
                pathVars.add(i)
        sys.path = list(pathVars)

        if argc < 2:
            raise RuntimeError("Insufficient arguments to wsgi handler")

        _proc = get_proc_handle(argv[1])

        medusa_wsgi = MedusaWSGI()
        _proc(medusa_wsgi)
        return 0
    except Exception, e:
        print "500\r\n\r\nCaught Exception: %s" % str(e)
        return 1


if __name__ == "__main__":
    sys.exit(main(len(sys.argv), sys.argv))
